
package com.feib.soeasy.action;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import com.feib.soeasy.model.Group;
import com.feib.soeasy.model.LabelValue;
import com.feib.soeasy.model.PaymentConfig;
import com.feib.soeasy.model.PaymentConfigItem;
import com.feib.soeasy.pagination.PaginatedList;
import com.feib.soeasy.service.GroupService;
import com.feib.soeasy.service.PaymentConfigService;
import com.feib.soeasy.util.UserUtil;

import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontBind;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.LocalizableMessage;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.StreamingResolution;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.SimpleError;
import net.sourceforge.stripes.validation.ValidationErrors;


/**
 * @title (#)Soez1019ActionBean.java<br>
 * @description 自動產生繳款單<br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2011/3/5 create by Jimmy Liu<br>
 */
public class Soez1019ActionBean extends BaseActionBean 
{
    /**
     * 作業畫面
     */
    private static final String DEFAULT_JSP = "/WEB-INF/views/soez1019/soez1019.jsp";
    
    private static final String AJAX_EDIT_JSP = "/WEB-INF/views/soez1019/soez1019Edit.jsp";
    
    private static final String PAYMENT_CONFIG_LIST_JSP = "/WEB-INF/views/soez1019/soez1019List.jsp";
    
    /**
     * 業者代號查詢畫面
     */
    private static final String AJAX_QUERY_GROUP_JSP = "/WEB-INF/views/soez1019/groupPopUpList.jsp";
    
    private static final String AJAX_CONFIG_NO_OPTIONS_JSP = "/WEB-INF/views/soez1019/soez1019Options.jsp";
    

    private PaymentConfig qryPaymentConfig;
    
    private PaginatedList<PaymentConfig> queryResult;
    
    private PaymentConfig editPaymentConfig;
    
    private List<LabelValue> confiNoOptions;;
    
    /**
     * 帳單業者查詢條件
     */
    private Group qryGroup;
    
    private String queryGroupTrigger;

    /**
     * 帳單業者查詢結果
     */
    private PaginatedList<Group> queryGroupResult;

    @SpringBean("paymentConfigService")
    private PaymentConfigService paymentConfigService;    

    @SpringBean("groupService")
    private GroupService groupService;
    
    @DontBind
    @DefaultHandler
    public Resolution doDefault()
    {
        return new ForwardResolution(DEFAULT_JSP); 
    }
    
    /**
     * 查詢
     * @return
     */
    public Resolution doAjaxQuery()
    {
        logger.debug("Enter doAjaxQuery mehtod.");
        try {
            //USER未輸入查詢條件，所以查詢物件會是NULL(查詢物件不可為NULL)
            if (null == qryPaymentConfig)
                qryPaymentConfig = new PaymentConfig();
            
            if (null == queryResult)
                queryResult = new PaginatedList<PaymentConfig>();


            //如果不是銀行端，則查詢條件要加入帳單業者限制
            if (!UserUtil.isBankGroup())
            {
                Group group = new Group();
                group.setGroupPk(UserUtil.getUserGroup().getGroupPk());
                qryPaymentConfig.setGroup(group);
            }

            queryResult = paymentConfigService.queryByPaymentConfig(qryPaymentConfig, queryResult) ;

        }
        catch (Exception e) {
            logger.error("自動產生繳款單查詢錯誤(Soez1019ActionBean.doAjaxQuery):", e);

            // 轉換錯誤訊息
            ValidationErrors errors = new ValidationErrors();
            errors.addGlobalError(new SimpleError("系統發生錯誤，請聯絡管理員！"));
            getContext().setValidationErrors(errors);
            // 回傳 錯誤 HTML fragments
            return super.errorsToHtmlStreams(errors);
        }

        return new ForwardResolution(PAYMENT_CONFIG_LIST_JSP);
    }
    
    public Resolution toAjaxAddPaymentConfig()
    {
        editPaymentConfig = new PaymentConfig();
        editPaymentConfig.setLimitDays(new Integer(45)); // default 45 天到期
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, 1);
        editPaymentConfig.setNextExcuteTime(cal.getTime()); // default 隔天執行
        cal.add(Calendar.DATE, editPaymentConfig.getLimitDays().intValue());
        editPaymentConfig.setPayDue(cal.getTime());
        
        // default
        List<PaymentConfigItem> paymentConfigItems = new ArrayList<PaymentConfigItem>();
        for(int i=0; i < 6; i++)
            paymentConfigItems.add(new PaymentConfigItem());
        editPaymentConfig.setPaymentConfigItems(paymentConfigItems);
        
        if (!UserUtil.isBankGroup())
        {
            editPaymentConfig.setGroup(UserUtil.getUserGroup());
        }
        
        return new ForwardResolution(AJAX_EDIT_JSP); 
    }
    
    public Resolution toAjaxEditPaymentConfig()
    {
        PaymentConfig dbPaymentConfig = this.paymentConfigService.queryByPk(this.editPaymentConfig.getPaymentConfigPk());
        
        // 使用copy方式，因為明細要有6個，如果不滿6個要補足，
        // 若是直接從hibernate物件加入，因為設定的關係，會自動將新增加的部分塞入資料庫，造成錯誤
        this.editPaymentConfig = new PaymentConfig();
        this.editPaymentConfig.setConfigName(dbPaymentConfig.getConfigName());
        this.editPaymentConfig.setConfigNo(dbPaymentConfig.getConfigNo());
        this.editPaymentConfig.setConfigNote(dbPaymentConfig.getConfigNote());
        this.editPaymentConfig.setCreatedBy(dbPaymentConfig.getCreatedBy());
        this.editPaymentConfig.setCreatedDate(dbPaymentConfig.getCreatedDate());
        this.editPaymentConfig.setCycleType(dbPaymentConfig.getCycleType());
        this.editPaymentConfig.setLimitDays(dbPaymentConfig.getLimitDays());
        this.editPaymentConfig.setNextExcuteTime(dbPaymentConfig.getNextExcuteTime());
        this.editPaymentConfig.setOfferAmount(dbPaymentConfig.getOfferAmount());
        this.editPaymentConfig.setPayDue(dbPaymentConfig.getPayDue());
        this.editPaymentConfig.setPaymentConfigPk(dbPaymentConfig.getPaymentConfigPk());
        this.editPaymentConfig.setUpdatedBy(dbPaymentConfig.getUpdatedBy());
        this.editPaymentConfig.setUpdatedDate(dbPaymentConfig.getUpdatedDate());
        
        Group group = new Group();
        group.setGroupPk(dbPaymentConfig.getGroup().getGroupPk());
        group.setGroupName(dbPaymentConfig.getGroup().getGroupName());
        group.setGroupNo(dbPaymentConfig.getGroup().getGroupNo());
        this.editPaymentConfig.setGroup(group);
        
        List<PaymentConfigItem> paymentConfigItems = new ArrayList<PaymentConfigItem>();
        for(PaymentConfigItem dbItem : dbPaymentConfig.getPaymentConfigItems())
        {
            PaymentConfigItem item = new PaymentConfigItem();
            item.setAmount(dbItem.getAmount());
            item.setConfigType(dbItem.getConfigType());
            item.setCreatedBy(dbItem.getCreatedBy());
            item.setCreatedDate(dbItem.getCreatedDate());
            item.setItemName(dbItem.getItemName());
            item.setPaymentConfig(editPaymentConfig);
            item.setPaymentConfigItemPk(dbItem.getPaymentConfigItemPk());
            item.setUpdatedBy(dbItem.getUpdatedBy());
            item.setUpdatedDate(dbItem.getUpdatedDate());
            paymentConfigItems.add(item);
        }
        
        while( paymentConfigItems.size() <= 6)
        {
            PaymentConfigItem item = new PaymentConfigItem();
            paymentConfigItems.add(item);
        }
        
        this.editPaymentConfig.setPaymentConfigItems(paymentConfigItems);
        return new ForwardResolution(AJAX_EDIT_JSP); 
    }
    
    /**
     * (新增/修改)
     * 
     * @return
     */
    public Resolution doAjaxSavePaymentConfig()
    {

        logger.debug("Enter doAjaxSavePaymentConfig method.");

        StringBuffer msg = new StringBuffer();
        
        try {
            
            if(this.editPaymentConfig.getPaymentConfigPk() == null)
            {
                Group group = null;
                //如果不是銀行端，則條件要加入帳單業者限制
                if (!UserUtil.isBankGroup())
                {
                    group = new Group();
                    group.setGroupPk(UserUtil.getUserGroup().getGroupPk());
                }
                else
                {
                    group = this.groupService.findByExactGroupNo(editPaymentConfig.getGroup().getGroupNo());
                }
                editPaymentConfig.setGroup(group);
                
                
                if (paymentConfigService.isDuplicateConfigNo(this.editPaymentConfig.getConfigNo(), editPaymentConfig.getGroup().getGroupPk()))
                {
                    msg.append("收費名稱 ").append(editPaymentConfig.getConfigNo()).append(" 已有使用.");
                }
                else
                {
                    this.editPaymentConfig.setPaymentConfigPk(null);
                    this.editPaymentConfig.setCreatedBy(UserUtil.getUserName());
                    this.editPaymentConfig.setCreatedDate(Calendar.getInstance().getTime());
                    this.editPaymentConfig.setUpdatedBy(UserUtil.getUserName());
                    this.editPaymentConfig.setUpdatedDate(Calendar.getInstance().getTime());
                    
                    List<PaymentConfigItem> htmlPaymentConfigItems = this.editPaymentConfig.getPaymentConfigItems();
                    if (null != htmlPaymentConfigItems)
                    {
                        List<PaymentConfigItem> paymentConfigItems = new ArrayList<PaymentConfigItem>();
                        for (PaymentConfigItem htmlItem : htmlPaymentConfigItems)
                        {
                            if (null == htmlItem || null == htmlItem.getConfigType())
                                continue;
                            
                            PaymentConfigItem item = new PaymentConfigItem();
                            item.setAmount(htmlItem.getAmount());
                            item.setConfigType(htmlItem.getConfigType());
                            item.setItemName(htmlItem.getItemName());
                            item.setPaymentConfig(editPaymentConfig);
                            
                            item.setCreatedBy(this.editPaymentConfig.getCreatedBy());
                            item.setCreatedDate(this.editPaymentConfig.getCreatedDate());
                            item.setUpdatedBy(this.editPaymentConfig.getUpdatedBy());
                            item.setUpdatedDate(this.editPaymentConfig.getUpdatedDate());
                            paymentConfigItems.add(item);
                        }
                        this.editPaymentConfig.setPaymentConfigItems(paymentConfigItems);
                        
                    }
                    
                    
                    this.editPaymentConfig = this.paymentConfigService.addPaymentConfig(editPaymentConfig);
                    msg.append("儲存成功").append("<input type='hidden' id='doAjaxSavePaymentConfigResultCode' value='1'/>"); 
                }
            }
            else
            {
                PaymentConfig paymentConfigInDb = this.paymentConfigService.queryByPk(this.editPaymentConfig.getPaymentConfigPk());
                
                paymentConfigInDb.setConfigNo(editPaymentConfig.getConfigNo());
                paymentConfigInDb.setConfigName(editPaymentConfig.getConfigName());
                //paymentConfigInDb.setConfigType(editPaymentConfig.getConfigType());
                paymentConfigInDb.setCycleType(editPaymentConfig.getCycleType());
                //paymentConfigInDb.setAmount(editPaymentConfig.getAmount());
                paymentConfigInDb.setOfferAmount(editPaymentConfig.getOfferAmount());
                paymentConfigInDb.setConfigNote(editPaymentConfig.getConfigNote());
                paymentConfigInDb.setNextExcuteTime(editPaymentConfig.getNextExcuteTime());
                paymentConfigInDb.setLimitDays(editPaymentConfig.getLimitDays());
                paymentConfigInDb.setPayDue(editPaymentConfig.getPayDue());
                
                List<PaymentConfigItem> dbPaymentConfigItems = paymentConfigInDb.getPaymentConfigItems();
                int dbIndx = 0;
                int htmlItemSize = 0;
                List<PaymentConfigItem> htmlPaymentConfigItems = this.editPaymentConfig.getPaymentConfigItems();
                if (null != htmlPaymentConfigItems)
                {
                    for (PaymentConfigItem htmlItem : htmlPaymentConfigItems)
                    {
                        if (null == htmlItem || null == htmlItem.getConfigType())
                            continue;
                        
                        htmlItemSize ++;
                        PaymentConfigItem item = null;
                        if (dbPaymentConfigItems.size() > dbIndx)
                        {
                            // 資料庫有，更新
                            item = dbPaymentConfigItems.get(dbIndx);
                            item.setAmount(htmlItem.getAmount());
                            item.setConfigType(htmlItem.getConfigType());
                            item.setItemName(htmlItem.getItemName());
                            dbIndx = dbIndx + 1;
                        }
                        else
                        {
                            // 資料庫沒有，新增
                            item = new PaymentConfigItem();
                            item.setPaymentConfig(paymentConfigInDb);
                            item.setAmount(htmlItem.getAmount());
                            item.setConfigType(htmlItem.getConfigType());
                            item.setItemName(htmlItem.getItemName());
                            item.setCreatedBy(UserUtil.getUserName());
                            item.setCreatedDate(Calendar.getInstance().getTime());
                            dbPaymentConfigItems.add(item);
                            dbIndx = dbIndx + 1;
                        }                    
                    }
                    
                }
                
                if (htmlItemSize < dbPaymentConfigItems.size())
                {
                    // 畫面上的筆數 < 資料庫中的筆數，就要把資料庫中多餘的刪除 
                    for (int i = dbPaymentConfigItems.size()-1; i >= htmlItemSize; i--)
                    {
                        dbPaymentConfigItems.set(i, null);
                    }
                }
                System.out.println("dbPaymentConfigItems.size()="+dbPaymentConfigItems.size());
                
                
                this.editPaymentConfig = this.paymentConfigService.save(paymentConfigInDb);
                msg.append("儲存成功").append("<input type='hidden' id='doAjaxSavePaymentConfigResultCode' value='1'/>");
            }
        }
        catch (Exception e) {
            logger.error("",e);
            msg.append("儲存失敗");
        }
        StreamingResolution resolution = new StreamingResolution("text/html", new StringReader(msg.toString()));
        resolution.setCharacterEncoding("UTF-8");
        return resolution;
    }
    
    /**
     * 刪除
     * @return
     */
    public Resolution doDeletePaymentConfig()
    {
        logger.debug("Enter doDeletePaymentConfig method.");

        StringBuffer msg = new StringBuffer();

        try {
            this.paymentConfigService.deletePaymentConfig(this.editPaymentConfig);
            msg.append("刪除成功").append("<input type='hidden' id='doAjaxDeletePaymentConfigResultCode' value='1'/>");
        }
        catch (Exception e) {
            logger.error("",e);
            msg.append("刪除失敗");
        }
        StreamingResolution resolution = new StreamingResolution("text/html", new StringReader(msg.toString()));
        resolution.setCharacterEncoding("UTF-8");
        return resolution;
    }
    
    /**
     * 帳單業者查詢
     * @return
     */
    public Resolution doAjaxQueryGroups()
    {
        logger.debug("Enter doAjaxQueryGroups mehtod.");
        try {
            //如果不是銀行端，則查詢條件要加入帳單業者限制
            if (!UserUtil.isBankGroup())
            {
                throw new Exception(new LocalizableMessage("no.authority").getMessage(getContext().getLocale()));
            }


            //USER未輸入查詢條件，所以查詢物件會是NULL(查詢物件不可為NULL)
            if (null == qryGroup)
            {
                qryGroup = new Group();
                qryGroup.setGroupType(Group.GROUP_TYPE_MANAGEMENT_COMMITTEE); //排除學校
            }

            //呼叫服務查詢
            queryGroupResult = groupService.queryByGroupExcludeBank(qryGroup, queryGroupResult);
        }
        catch (Exception e) {
            logger.error("自動產生繳款單-帳單業者查詢錯誤(Soez1019ActionBean.doAjaxQueryGroups):", e);

            // 轉換錯誤訊息
            ValidationErrors errors = new ValidationErrors();
            errors.addGlobalError(new SimpleError("查詢錯誤！"));
            getContext().setValidationErrors(errors);
            // 回傳 錯誤 HTML fragments
            return super.errorsToHtmlStreams(errors);
        }

        return new ForwardResolution(AJAX_QUERY_GROUP_JSP);
    }
    
    public Resolution doAjaxGroupNoChange()
    {
        return new ForwardResolution(AJAX_CONFIG_NO_OPTIONS_JSP);
    }

    
    
    /**
     * @return the confiNoOptions
     */
    public List<LabelValue> getConfiNoOptions() {
        
        if (null == this.confiNoOptions)
        {
            //如果不是銀行端，則查詢條件要加入帳單業者限制
            if (!UserUtil.isBankGroup())
            {
                // 查詢條件
                PaymentConfig paymentConfig = new PaymentConfig();
                Group group = new Group();
                group.setGroupNo(UserUtil.getUserGroup().getGroupNo());
                group.setGroupPk(UserUtil.getUserGroup().getGroupPk());
                group.setGroupType(Group.GROUP_TYPE_MANAGEMENT_COMMITTEE); //排除學校
                paymentConfig.setGroup(group);
                confiNoOptions = paymentConfigService.findLabelValueByPaymentConfig(paymentConfig);
            }
            else
            {
                // 銀行端，看是否有群組代碼，若沒有則回傳空陣列
                if (null != this.qryPaymentConfig && null != this.qryPaymentConfig.getGroup())
                {
                    // 查詢條件
                    PaymentConfig paymentConfig = new PaymentConfig();
                    paymentConfig.setGroup(this.qryPaymentConfig.getGroup());
                    this.qryPaymentConfig.getGroup().setGroupType(Group.GROUP_TYPE_MANAGEMENT_COMMITTEE); //排除學校
                    confiNoOptions = paymentConfigService.findLabelValueByPaymentConfig(paymentConfig);
                }
                else
                {
                    this.confiNoOptions = new ArrayList<LabelValue>();                    
                }

            }
        }
            
        return confiNoOptions;
    }

    
    /**
     * @param confiNoOptions the confiNoOptions to set
     */
    public void setConfiNoOptions(List<LabelValue> confiNoOptions) {
        this.confiNoOptions = confiNoOptions;
    }

    /**
     * @return the qryPaymentConfig
     */
    public PaymentConfig getQryPaymentConfig() {
        return qryPaymentConfig;
    }

    
    /**
     * @param qryPaymentConfig the qryPaymentConfig to set
     */
    public void setQryPaymentConfig(PaymentConfig qryPaymentConfig) {
        this.qryPaymentConfig = qryPaymentConfig;
    }

    
    /**
     * @return the queryResult
     */
    public PaginatedList<PaymentConfig> getQueryResult() {
        return queryResult;
    }

    
    /**
     * @param queryResult the queryResult to set
     */
    public void setQueryResult(PaginatedList<PaymentConfig> queryResult) {
        this.queryResult = queryResult;
    }

    
    /**
     * @return the qryGroup
     */
    public Group getQryGroup() {
        return qryGroup;
    }

    
    /**
     * @param qryGroup the qryGroup to set
     */
    public void setQryGroup(Group qryGroup) {
        this.qryGroup = qryGroup;
    }

    
    /**
     * @return the queryGroupResult
     */
    public PaginatedList<Group> getQueryGroupResult() {
        return queryGroupResult;
    }

    
    /**
     * @param queryGroupResult the queryGroupResult to set
     */
    public void setQueryGroupResult(PaginatedList<Group> queryGroupResult) {
        this.queryGroupResult = queryGroupResult;
    }

    
    /**
     * @return the editPaymentConfig
     */
    public PaymentConfig getEditPaymentConfig() {
        return editPaymentConfig;
    }

    
    /**
     * @param editPaymentConfig the editPaymentConfig to set
     */
    public void setEditPaymentConfig(PaymentConfig editPaymentConfig) {
        this.editPaymentConfig = editPaymentConfig;
    }

    
    /**
     * @return the queryGroupTrigger
     */
    public String getQueryGroupTrigger() {
        return queryGroupTrigger;
    }

    
    /**
     * @param queryGroupTrigger the queryGroupTrigger to set
     */
    public void setQueryGroupTrigger(String queryGroupTrigger) {
        this.queryGroupTrigger = queryGroupTrigger;
    }
}
